package com.actionpals.components.controls
{
	import com.actionpals.enum.Align;
	import com.actionpals.enum.InvalidationType;
	import com.actionpals.events.ComponentEvent;
	
	import flash.display.DisplayObject;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	
	public class LabelButton extends BaseButton
	{
		protected var _labelField:TextField;
		protected var _labelPlacement:String;
		protected var _icon:DisplayObject;
		protected var _upIconState:DisplayObject;
		protected var _overIconState:DisplayObject;
		protected var _downIconState:DisplayObject;
		protected var _disabledIconState:DisplayObject;
		protected var _selectedUpIconState:DisplayObject;
		protected var _selectedOverIconState:DisplayObject;
		protected var _selectedDownIconState:DisplayObject;
		protected var _selectedDisabledIconState:DisplayObject;
		protected var _label:String = "";
		protected var _paddingBottom:Number = 0;
		protected var _paddingTop:Number = 0;
		protected var _iconPadding:Number = 6;
		
		public function LabelButton()
		{			
			super();
			_paddingLeft = 10;
			_paddingRight = 10;
		}
		
		public function get labelField():TextField
		{
			return _labelField;
		}
		public function set labelField( field:TextField ):void
		{
			_labelField = field;
		}
		
		public function get label():String
		{
			return _label;
		}
		public function set label( value:String ):void
		{
			_label = value;
			if( labelField.text != _label )
			{
				labelField.text = _label;
				dispatchEvent( new ComponentEvent( ComponentEvent.LABEL_CHANGE ) );
			}
			invalidate( InvalidationType.SIZE );
			invalidate( InvalidationType.STYLES );
		}
		
		public function get labelPlacement():String
		{
			return _labelPlacement ? _labelPlacement : _icon ? Align.RIGHT : Align.TOP;
		}
		public function set labelPlacement( value:String ):void
		{
			_labelPlacement = value;
			invalidate( InvalidationType.SIZE );
		}
		
		public function get upIconState():DisplayObject
		{
			return _upIconState;
		}
		public function set upIconState( value:DisplayObject ):void
		{
			_upIconState = value;
		}
		
		public function get overIconState():DisplayObject
		{
			return _overIconState ? _overIconState : upIconState;
		}
		public function set overIconState( value:DisplayObject ):void
		{
			_overIconState = value;
		}
		
		public function get downIconState():DisplayObject
		{
			return _downIconState ? _downIconState : overIconState;
		}
		public function set downIconState( value:DisplayObject ):void
		{
			_downIconState = value;
		}
		
		public function get disabledIconState():DisplayObject
		{
			return _disabledIconState ? _disabledIconState : upIconState;
		}
		public function set disabledIconState( value:DisplayObject ):void
		{
			_disabledIconState = value;
		}
		
		public function get selectedUpIconState():DisplayObject
		{
			return _selectedUpIconState ? _selectedUpIconState : upIconState;
		}
		public function set selectedUpIconState( value:DisplayObject ):void
		{
			_selectedUpIconState = value;
		}
		
		public function get selectedOverIconState():DisplayObject
		{
			return _selectedOverIconState ? _selectedOverIconState : overIconState;
		}
		public function set selectedOverIconState( value:DisplayObject ):void
		{
			_selectedOverIconState = value;
		}
		
		public function get selectedDownIconState():DisplayObject
		{
			return _selectedDownIconState ? _selectedDownIconState : downIconState;
		}
		public function set selectedDownIconState( value:DisplayObject ):void
		{
			_selectedDownIconState = value;
		}
		
		public function get selectedDisabledIconState():DisplayObject
		{
			return _selectedDisabledIconState ? _selectedDisabledIconState : disabledIconState;
		}
		public function set selectedDisabledIconState( value:DisplayObject ):void
		{
			_selectedDisabledIconState = value;
		}
		
		public function get paddingBottom():Number
		{
			return _paddingBottom;
		}
		public function set paddingBottom( value:Number ):void
		{
			_paddingBottom = value;
		}
		
		public function get paddingTop():Number
		{
			return _paddingTop;
		}
		public function set paddingTop( value:Number ):void
		{
			_paddingTop = value;
		}
		
		public function get iconPadding():Number
		{
			return _iconPadding;
		}
		public function set iconPadding( value:Number ):void
		{
			_iconPadding = value;
		}
		
		protected override function init():void
		{
			super.init();
			
			labelField = new TextField();
			labelField.autoSize = TextFieldAutoSize.LEFT;
			labelField.text = "";
			labelField.type = TextFieldType.DYNAMIC;
			labelField.selectable = false;
			addChild( labelField );
		}
		
		protected override function draw():void
		{
			if( labelField.text != _label )
			{ 
				label = _label;
			}
			
			if( isInvalid( InvalidationType.STYLES, InvalidationType.STATE ) )
			{
				drawBackground();
				drawIcon();
				drawTextFormat();
				
				invalidate( InvalidationType.SIZE );
			}
			if( isInvalid( InvalidationType.SIZE, InvalidationType.STYLES ) )
			{
				drawLayout();
				if( _isFocused ) { drawFocus( true ); }
			}
			validate();
		}
		
		protected function drawIcon():void
		{
			var oldIcon:DisplayObject = _icon;
			var state:String = enabled ? _mouseState : "disabled";
			if( _selected ) { state = "selected" + state.substr( 0, 1 ).toUpperCase() + state.substr( 1 ); }
			state += "IconState";
			_icon = this[ state ];
			if( _icon ) addChildAt( _icon, 1 );
			if( oldIcon != null && oldIcon != _icon ) { removeChild( oldIcon ); }
		}
		
		protected function drawTextFormat():void
		{
			var tf:TextFormat = enabled ? textFormat : disabledTextFormat;
			labelField.setTextFormat( tf );
			var defaultTF:TextFormat = enabled ? defaultTextFormat : defaultDisabledTextFormat;
			labelField.defaultTextFormat = defaultTF;
			
			setEmbedFont();
		}
		
		protected function setEmbedFont():void
		{
			if( embedFonts )
			{
				labelField.embedFonts = embedFonts;
			}
		}
		
		protected override function drawLayout():void
		{
			labelField.height = labelField.textHeight + 4;
			
			var txtW:Number = labelField.textWidth + 4;
			var txtH:Number = labelField.textHeight + 4;
			
			var paddedIconW:Number = !_icon ? 0 : _icon.width + iconPadding;
			var paddedIconH:Number = !_icon ? 0 : _icon.height + iconPadding;
			labelField.visible = ( label.length > 0 );
			
			if( _icon )
			{
				_icon.x = Math.round( ( width - _icon.width )/2 );
				_icon.y = Math.round( ( height - _icon.height )/2 );
			}
			
			var tmpWidth:Number;
			var tmpHeight:Number;
			
			if( labelField.visible == false )
			{
				labelField.width = 0;
				labelField.height = 0;
			}
			else if( labelPlacement == Align.BOTTOM || labelPlacement == Align.TOP )
			{
				tmpWidth = Math.max( 0, Math.min( txtW, width - paddingLeft - paddingRight ) );
				if( height - 2 > txtH )
				{
					tmpHeight = txtH;
				}
				else
				{
					tmpHeight = height - 2;
				}
				
				labelField.width = txtW = tmpWidth;
				labelField.height = txtH = tmpHeight;
				
				labelField.x = Math.round( ( width - txtW )/2 );
				labelField.y = Math.round( ( height - labelField.height - paddedIconH )/2 + ( ( labelPlacement == Align.BOTTOM ) ? paddedIconH : 0 ) );
				if( _icon )
				{
					_icon.y = Math.round( ( labelPlacement == Align.BOTTOM ) ? labelField.y - paddedIconH : labelField.y + labelField.height + paddingTop );
				}
			}
			else
			{
				tmpWidth =  Math.max( 0, Math.min( txtW, width - paddedIconW - paddingLeft - paddingRight ) );
				labelField.width = txtW = tmpWidth;	
				
				labelField.x = Math.round( ( width - txtW - paddedIconW )/2 + ( ( labelPlacement != Align.LEFT ) ? paddedIconW : 0 ) );
				labelField.y = Math.round( ( height - labelField.height )/2 );
				if( _icon )
				{
					_icon.x = Math.round( ( labelPlacement != Align.LEFT ) ? labelField.x - paddedIconW : labelField.x + txtW + paddingLeft );
				}
			}
			
			// Now shift everything based on TextFormat.align style
			var tf:TextFormat = enabled ? textFormat : disabledTextFormat;
			var align:String = tf.align ? tf.align : TextFormatAlign.CENTER;
			
			if( align != TextFormatAlign.CENTER )
			{
				if( align == TextFormatAlign.LEFT )
				{
					if( _icon ) _icon.x -= ( _icon.x - paddingLeft );
					labelField.x -= ( labelField.x - paddingLeft );
				}
				else if( align == TextFormatAlign.RIGHT )
				{
					if( _icon ) _icon.x += ( _icon.x - paddingRight );
					labelField.x += ( labelField.x - paddingRight );
				}
			}
			
			super.drawLayout();			
		}
		
	}
}